package co.gov.medellin.ssti.sub.service;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

import javax.naming.NamingException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

import co.gov.medellin.ssti.sub.common.ConexionFactory;
import co.gov.medellin.ssti.sub.common.dao.TransactionUtil;
import co.gov.medellin.ssti.sub.common.excepcion.SUBException;
import co.gov.medellin.ssti.sub.model.dao.DAOFactory;
import co.gov.medellin.ssti.sub.model.dao.IBeneficioDAO;
import co.gov.medellin.ssti.sub.model.dao.exception.DAOException;
import co.gov.medellin.ssti.sub.model.vo.Beneficiario_AtributoVO;
import co.gov.medellin.ssti.sub.model.vo.BeneficioVO;
import co.gov.medellin.ssti.sub.model.vo.UsuarioxSedeVO;

public class BeneficioService {

	/**
	 * Metodo que consulta si el beneficiario identificado por codeBeneficiario
	 * tiene algun beneficio para un subprograma identificado por
	 * codeSubprograma.
	 * 
	 * @param codeBeneficiario
	 *            Codigo del beneficiario.
	 * @param codeSubprograma
	 *            Codigo del subprograma.
	 * @return
	 * @throws DAOException
	 */
	public boolean isExisteBeneficiario(Long codeBeneficiario,
			Long codeSubprograma) throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			return beneficioDAO.isExisteBeneficiario(codeBeneficiario,
					codeSubprograma);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
	}

	/**
	 * Metodo que retorna el costo del beneficio identificado por codeBeneficio.
	 * 
	 * @param codeBeneficio
	 *            Codigo del beneficio.
	 * @return String representando el costo del beneficio.
	 * @throws DAOException
	 */
	public String findCostoBeneficio(Long codeBeneficio) throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			return beneficioDAO.findCostoBeneficio(codeBeneficio);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
	}

	/**
	 * Metodo que consulta el costo del beneficio otorgado identificado por
	 * codeBot.
	 * 
	 * @param codeBot
	 *            Codigo del beneficio otorgado.
	 * @return
	 * @throws DAOException
	 */
	public String findCostoBOT(Long codeBot) throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			return beneficioDAO.findCostoBOT(codeBot);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
	}

	/**
	 * Metodo que consulta la fecha de un beneficio otorgado.
	 * 
	 * @param codeBot
	 *            Codigo del beneficio otorgado.
	 * @return String representando la fecha del beneficio otorgado
	 *         (dd/mm/RRRR).
	 * @throws DAOException
	 */
	public String findFechaBOT(Long codeBot) throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			return beneficioDAO.findFechaBOT(codeBot);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
	}

	/**
	 * Metodo que consulta el valor TERCERO de un beneficio otorgado.
	 * 
	 * @param codeBot
	 *            Codigo del beneficio otorgado.
	 * @return Valor TERCERO para el beneficio otorgado.
	 * @throws DAOException
	 */
	public String findTercero(Long codeBot) throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			return beneficioDAO.findTercero(codeBot);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
	}

	/**
	 * Metodo que consulta el TIPO_BENEFICIO de un beneficio otorgado.
	 * 
	 * @param codeBot
	 *            Codigo del beneficio otorgado.
	 * @return Valor TIPO_BENEFICIO para el beneficio otorgado.
	 * @throws DAOException
	 */
	public String findTipoBeneficio(Long codeBot) throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			return beneficioDAO.findTipoBeneficio(codeBot);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
	}

	/**
	 * Metodo que consulta NUMERO_BEN_DISPONIBLE en TCS_BEN_SUBPROGRAMA_SEDE
	 * donde SEDE_CODIGO = codeSede y SBPR_CODIGO = codeSubprograma.
	 * 
	 * @param codeSede
	 *            Codigo de la sede.
	 * @param codeSubprograma
	 *            Codigo del subprograma.
	 * @return Valor NUMERO_BEN_DISPONIBLE.
	 * @throws DAOException
	 */
	public int findDisponibilidad(Long codeSede, Long codeSubprograma)
			throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			return beneficioDAO.findDisponibilidad(codeSede, codeSubprograma);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
	}

	/**
	 * 
	 * @param codeSede
	 * @param codeSubprograma
	 * @param codeBeneficiario
	 * @param lListaInsertar
	 * @param tercero
	 * @param i
	 * @param strArrIns
	 * @param costoBeneficio
	 * @param fechaBeneficio
	 * @return
	 * @throws DAOException
	 */
	public boolean otorgarBeneficios(Long codeSede, Long codeSubprograma,
			Long codeBeneficiario,
			List<Beneficiario_AtributoVO> lListaInsertar, String tercero,
			int i, String strArrIns[], String costoBeneficio,
			String fechaBeneficio) throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		Connection con;
		try {
			con = ConexionFactory.getInstance().getConnection();

			boolean autoCommitState = con.getAutoCommit();
			con.setAutoCommit(false);

			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			UserTransaction utx = null;
			utx = TransactionUtil.getUserTransaction();

			try {
				// Inicio transaction.
				utx.begin();
				beneficioDAO.otorgarBeneficios(codeSede, codeSubprograma,
						codeBeneficiario, lListaInsertar, tercero, i,
						strArrIns, costoBeneficio, fechaBeneficio);
				// Fin - Commit transaction.
				utx.commit();
				// retornar al estado original de autocommit de la connection.
				con.setAutoCommit(autoCommitState);
				return true;
			} catch (Exception e) {
				if (utx != null) {
					try {
						// Rollback si hay error.
						utx.rollback();
					} catch (SystemException sysex) {
						SUBException.logDebugError(
								"otorgarBeneficios.otorgarBeneficios: ", sysex);
					}
				}
			}
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
		return false;
	}

	/**
	 * 
	 * @param codeSede
	 * @param codeSubprograma
	 * @param codeBeneficiario
	 * @param lListaInsertar
	 * @param tercero
	 * @param i
	 * @param strArrIns
	 * @param costoBeneficio
	 * @param fechaBeneficio
	 * @param tipoBeneficio
	 * @return
	 * @throws DAOException
	 */
	public boolean otorgarBeneficios(Long codeSede, Long codeSubprograma,
			Long codeBeneficiario,
			List<Beneficiario_AtributoVO> lListaInsertar, String tercero,
			int i, String strArrIns[], String costoBeneficio,
			String fechaBeneficio, String tipoBeneficio) throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		Connection con;
		try {
			con = ConexionFactory.getInstance().getConnection();

			boolean autoCommitState = con.getAutoCommit();
			con.setAutoCommit(false);

			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			UserTransaction utx = null;
			utx = TransactionUtil.getUserTransaction();

			try {
				// Inicio transaction.
				utx.begin();
				beneficioDAO.otorgarBeneficios(codeSede, codeSubprograma,
						codeBeneficiario, lListaInsertar, tercero, i,
						strArrIns, costoBeneficio, fechaBeneficio,
						tipoBeneficio);
				// Fin - Commit transaction.
				utx.commit();
				// retornar al estado original de autocommit de la connection.
				con.setAutoCommit(autoCommitState);
				return true;
			} catch (Exception e) {
				if (utx != null) {
					try {
						// Rollback si hay error.
						utx.rollback();
					} catch (SystemException sysex) {
						SUBException.logDebugError(
								"otorgarBeneficios.otorgarBeneficios: ", sysex);
					}
				}
			}
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
		return false;
	}

	/**
	 * 
	 * @param codeSede
	 * @param codeSubprograma
	 * @param codeBeneficiario
	 * @param lListaInsertar
	 * @param tercero
	 * @param i
	 * @param strArrIns
	 * @param costoBeneficio
	 * @param fechaBeneficio
	 * @param codeBot
	 * @param codeSedeOld
	 * @param tipoBot
	 * @return
	 * @throws DAOException
	 */
	public boolean updateBOT(Long codeSede, Long codeSubprograma,
			Long codeBeneficiario,
			List<Beneficiario_AtributoVO> lListaInsertar, String tercero,
			int i, String strArrIns[], String costoBeneficio,
			String fechaBeneficio, Long codeBot, Long codeSedeOld,
			String tipoBot) throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		Connection con;
		try {
			con = ConexionFactory.getInstance().getConnection();

			boolean autoCommitState = con.getAutoCommit();
			con.setAutoCommit(false);

			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			UserTransaction utx = null;
			utx = TransactionUtil.getUserTransaction();

			try {
				// Inicio transaction.
				utx.begin();
				boolean ret = beneficioDAO.updateBOT(codeSede, codeSubprograma,
						codeBeneficiario, lListaInsertar, tercero, i,
						strArrIns, costoBeneficio, fechaBeneficio, codeBot,
						codeSedeOld, tipoBot);
				if (!ret) {
					throw new DAOException("not updated.");
				}
				System.out.println(ret);
				// Fin - Commit transaction.
				utx.commit();
				// retornar al estado original de autocommit de la connection.
				con.setAutoCommit(autoCommitState);
				return true;
			} catch (Exception e) {
				SUBException.logDebugError("", e);
				if (utx != null) {
					try {
						// Rollback si hay error.
						utx.rollback();
					} catch (SystemException sysex) {
						SUBException.logDebugError(
								"otorgarBeneficios.otorgarBeneficios: ", sysex);
					}
				}
			}
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
		return false;
	}

	/**
	 * 
	 * @param codeBot
	 * @return
	 * @throws DAOException
	 */
	public String findSedeBOT(String codeBot) throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			return beneficioDAO.findSedeBOT(codeBot);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
	}

	/**
	 * 
	 * @param codeBeneficio
	 * @param codeSubprograma
	 * @return
	 * @throws DAOException
	 */
	public Collection<BeneficioVO> findDetallesBeneficios(Long codeBeneficio,
			Long codeSubprograma) throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			return beneficioDAO.findDetallesBeneficios(codeBeneficio,
					codeSubprograma);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
	}

	/**
	 * 
	 * @param codeBOT
	 * @return
	 * @throws DAOException
	 */
	public boolean deleteBOT(String codeBOT) throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		Connection con;
		try {
			con = ConexionFactory.getInstance().getConnection();

			boolean autoCommitState = con.getAutoCommit();
			con.setAutoCommit(false);

			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			UserTransaction utx = null;
			utx = TransactionUtil.getUserTransaction();

			try {
				// Inicio transaction.
				utx.begin();
				beneficioDAO.deleteBOT(codeBOT);
				// Fin - Commit transaction.
				utx.commit();
				// retornar al estado original de autocommit de la connection.
				con.setAutoCommit(autoCommitState);
				return true;
			} catch (Exception e) {
				if (utx != null) {
					try {
						// Rollback si hay error.
						utx.rollback();
					} catch (SystemException sysex) {
						SUBException.logDebugError(
								"otorgarBeneficios.deleteBOT: ", sysex);
					}
				}
			}
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
		return false;
	}

	/**
	 * Metodo que consulta si el usuario tiene permiso para eliminar el
	 * beneficio otorgado.
	 * 
	 * @param groupUserName
	 *            Nombre del grupo al que pertenece el usuario.
	 * @param userName
	 *            Nombre del usuario.
	 * @param codeBOT
	 *            Codigo del beneficio otorgado.
	 * @return true si tiene permiso, false de lo contrario.
	 * @throws DAOException
	 */
	public boolean validarDeleteBOT(String groupUserName, String userName,
			Long codeBOT) throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			return beneficioDAO.validarDeleteBOT(groupUserName, userName,
					codeBOT);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
	}

	/**
	 * Metodo que consulta si el usuario tiene permiso para modificar el
	 * beneficio otorgado.
	 * 
	 * @param groupUserName
	 *            Nombre del grupo al que pertenece el usuario.
	 * @param userName
	 *            Nombre del usuario.
	 * @param codeBOT
	 *            Codigo del beneficio otorgado.
	 * @return true si tiene permiso, false de lo contrario.
	 * @throws DAOException
	 */
	public boolean validarEditBOT(String groupUserName, String userName,
			Long codeBOT) throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			return beneficioDAO
					.validarEditBOT(groupUserName, userName, codeBOT);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
	}

	public boolean renewBeneficio(Long codeSubpro, Long codeBeneficiario,
			Long codeOldSede, Long codeNewSede, String fechaOtorgamiento)
			throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			return beneficioDAO.renewBeneficio(codeSubpro, codeBeneficiario,
					codeOldSede, codeNewSede, fechaOtorgamiento);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
	}

	public Collection<UsuarioxSedeVO> findUsuarioxBeneficio(String idben)
			throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			return beneficioDAO.findUsuarioxBeneficio(idben);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
	}

	public String findPrograma(String codeSubprograma) throws DAOException {
		IBeneficioDAO beneficioDAO = null;
		try {
			Connection con = ConexionFactory.getInstance().getConnection();
			beneficioDAO = DAOFactory.getDAOFactory(DAOFactory.ORACLE)
					.getBeneficioDAO(con);
			return beneficioDAO.findPrograma(codeSubprograma);
		} catch (NamingException e) {
			throw new DAOException(e);
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			if (beneficioDAO != null) {
				if (!beneficioDAO.isConnClosed()) {
					beneficioDAO.close();
				}
			}
		}
	}
}
